package com.jblv.frame.config.service;

import com.alibaba.fastjson.JSONObject;
import com.jblv.frame.config.bean.AppInfo;
import com.jblv.frame.config.bean.Config;
import com.jblv.frame.config.bean.JblvConfig;
import com.jblv.frame.config.constans.ApplicationLabelEnum;
import com.jblv.frame.config.database.dao.JblvConfigRepository;
import com.jblv.frame.config.util.ConfigXmlUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.yaml.snakeyaml.Yaml;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.*;

/**
 * @author happyonion.yangtao
 * @version 1.0
 * @title ConfigServiceImpl
 * @projectName jblv-frame
 * @packageName com.jblv.frame.config.service
 * @description 基础服务
 * @date Create at 2020/9/7 15:34
 * @since jdk1.8
 */
@Service
public class ConfigServiceImpl implements ConfigService {

    private final static Logger logger = LoggerFactory.getLogger(ConfigServiceImpl.class);

//    @Autowired
//    private MongoTemplate mongoTemplate;

    @Autowired
    private JblvConfigRepository jblvConfigRespository;

    @Value("${jblv.config.location}")
    private String location = "";
    private final String YML_CONFIG_NAME = "config-license-dev.yml";

    @Override
    public JSONObject getConfigFromDB(String appId, String appNode) throws Exception {
        List<JblvConfig> list = new ArrayList<JblvConfig>();

        JSONObject json = new JSONObject(true);
        list = jblvConfigRespository.findAll();
        for (final JblvConfig jblvConfig : list) {
            Config config = new Config();
            config.setName(jblvConfig.getConfig_name());
            config.setDesc(jblvConfig.getConfig_desc());
            config.setValue(jblvConfig.getConfig_value());
            config.setType(2);
            config.setAppId(jblvConfig.getApp_id());
            config.setAppNode(jblvConfig.getApp_node());
            json.put(jblvConfig.getConfig_name(),config);
        }
        return  json;
    }

//    @Override
//    public JSONObject getConfigFromMongoDB(final String appId, final String appNode) throws Exception {
//        final List<LicenseConfig> list = new ArrayList<LicenseConfig>();
//        final Query query = new Query();
//        final Criteria criteria = Criteria.where("status").is((Object)1);
//        if (!StringUtils.isBlank(appId) && !StringUtils.isBlank(appNode)) {
//            criteria.and("app_id").in(new Object[] { appId, "" });
//            criteria.and("app_node").in(new Object[] { appNode, "" });
//        }
//        query.addCriteria((CriteriaDefinition)criteria);
//        list.addAll(this.mongoTemplate.find(query, (Class)LicenseConfig.class));
//        final JSONObject json = new JSONObject(true);
//        for (final LicenseConfig licenseConfig : list) {
//            final Config config = new Config();
//            config.setName(licenseConfig.getConfigName());
//            config.setDesc(licenseConfig.getConfigDesc());
//            config.setValue(licenseConfig.getConfigValue());
//            config.setType(2);
//            config.setAppId(licenseConfig.getAppId());
//            config.setAppNode(licenseConfig.getAppNode());
//            json.put(licenseConfig.getConfigName(), (Object)config);
//        }
//        return json;
//    }

    @Override
    public JSONObject getConfigFromXML(final String fileName) throws Exception {
        final String path = location + File.separator + fileName + ".xml";
        return ConfigXmlUtils.load(path);
    }

    @Override
    public JSONObject getConfigFromYml() throws Exception {
        InputStream in = null;
        try {
            final Yaml yaml = new Yaml();
            final String path = location + File.separator + "config-license-dev.yml";
            final ResourceLoader resourceLoader = new DefaultResourceLoader();
            final Resource resource = resourceLoader.getResource(path);
            in = resource.getInputStream();
            final Map<String, Object> map = yaml.load(in);
            if (map == null) {
                return new JSONObject();
            }
            final JSONObject json = new JSONObject();
            for (final String key : map.keySet()) {
                this.resolveConfigYML(map.get(key), key, json);
            }
            logger.debug(json.toJSONString());
            return json;
        }
        catch (FileNotFoundException e2) {
            return new JSONObject();
        }
        catch (Exception e) {
            logger.error(e.getMessage(), e);
            return new JSONObject();
        }
        finally {
            if (in != null) {
                in.close();
            }
        }
    }

    private void resolveConfigYML(final Object object, final String name, final JSONObject json) {
        if (object instanceof Map) {
            final Map<String, Object> map = (Map<String, Object>)object;
            for (final String key : map.keySet()) {
                final String n = name + "." + key;
                this.resolveConfigYML(map.get(key), n, json);
            }
            return;
        }
        final Config config = new Config();
        config.setName(name);
        config.setDesc("开发自定义");
        config.setValue(object.toString());
        config.setType(3);
        json.put(name, config);
    }

    @Override
    public List<AppInfo>   getAppList(final String fileName) throws Exception {
        final String path = location + File.separator + fileName + ".xml";
        final JSONObject json = ConfigXmlUtils.load(path);
        final List<AppInfo> apps = new ArrayList<>();
        for (final ApplicationLabelEnum label : ApplicationLabelEnum.values()) {
            final String id = label.getLabel() + ".id";
            final String name = label.getLabel() + ".name";
            final String host = label.getLabel() + ".host";
            final AppInfo app = new AppInfo();
            app.setId(json.getJSONObject(id).getString("value"));
            app.setName(json.getJSONObject(name).getString("value"));
            app.setHost(json.getJSONObject(host).getString("value"));
            apps.add(app);
        }
        return apps;
    }

    @Override
    public AppInfo getAppList(final String host, final JSONObject json) throws Exception {
        AppInfo app = null;
        for (final ApplicationLabelEnum label : ApplicationLabelEnum.values()) {
            final String id = label.getLabel() + ".id";
            final String name = label.getLabel() + ".name";
            final String hosts = label.getLabel() + ".host";
            final String value = json.getJSONObject(hosts).getString("value");
            if (!StringUtils.isBlank(value)) {
                final String[] values = value.split(",");
                final Set<String> s = new HashSet<String>(values.length);
                for (final String v : values) {
                    s.add(v);
                }
                if (s.contains(host)) {
                    app = new AppInfo();
                    app.setId(json.getJSONObject(id).getString("value"));
                    app.setName(json.getJSONObject(name).getString("value"));
                    app.setHost(host);
                    app.setType(label.getType());
                    break;
                }
            }
        }
        return app;
    }

}
